<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\App\WorkMessage\Action\Dashboard;

use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use MoChat\App\Common\Middleware\DashboardAuthMiddleware;
use MoChat\App\User\Logic\Traits\UserTrait;
use MoChat\App\WorkContact\Contract\WorkContactContract;
use MoChat\App\WorkContact\Contract\WorkContactEmployeeContract;
use MoChat\App\WorkContact\Contract\WorkContactRoomContract;
use MoChat\App\WorkEmployee\Contract\WorkEmployeeContract;
use MoChat\App\WorkMessage\Constants\MsgType;
use MoChat\App\WorkMessage\Contract\WorkMessageContract;
use MoChat\App\WorkMessage\Contract\WorkMessageIndexContract;
use MoChat\App\WorkRoom\Contract\WorkRoomContract;
use MoChat\Framework\Action\AbstractAction;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;

/**
 * @Controller
 */
class ContactMessage extends AbstractAction
{
    use UserTrait;

    /**
     * @var WorkMessageContract
     */
    protected $workMessageService;

    /**
     * @Inject
     * @var WorkContactEmployeeContract
     */
    protected $workContactEmployeeService;

    /**
     * @Inject
     * @var WorkContactRoomContract
     */
    protected $workContactRoomService;

    /**
     * @Inject
     * @var WorkEmployeeContract
     */
    protected $workEmployeeService;

    /**
     * @Inject
     * @var WorkContactContract
     */
    protected $workContactService;

    /**
     * @Inject
     * @var WorkRoomContract
     */
    protected $workRoomClient;

    /**
     * @Inject
     * @var WorkMessageIndexContract
     */
    protected $workMsgIndexService;

    /**
     * @Middlewares({
     *     @Middleware(DashboardAuthMiddleware::class)
     * })
     * @RequestMapping(path="/dashboard/workMessage/contactMessage", methods="GET")
     */
    public function handle(): array
    {
        // 请求参数.验证
        $corpId = $this->corpId();
        $this->workMessageService = make(WorkMessageContract::class, [$corpId]);

        $workContactId = (int) $this->request->query('workContactId');
        $contactData = $this->workContactService->getWorkContactById($workContactId);
        if (! $contactData) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '客户不存在');
        }

        $options = [
            'page' => $this->request->query('page', 1),
            'perPage' => $this->request->query('perPage', 10),
        ];

        $name = $this->request->query('name');
        $toUserType = (int) $this->request->query('toUsertype', 0);
        $where = [
            ['corp_id', '=', $corpId],
        ];
        if (! empty($name)) {
            $where[] = ['name', 'like', '%' . $name . '%'];
        }

        $data = [];
        if ($toUserType == 1) {
            $toData = $this->workContactEmployeeService->getWorkContactEmployeesByContactIdCorpId($workContactId, $corpId);
            $employeeIds = array_column($toData, 'employeeId');
            if (empty($employeeIds)) {
                return [];
            }
            $where[] = ['id', 'in', $employeeIds];
            $employeeList = $this->workEmployeeService->getWorkEmployeeList($where, ['*'], $options);
            foreach ($employeeList['data'] as $k => $v) {
                $lastMsg = $this->getLastMsg($v['wxUserId'], $contactData['wxExternalUserid']);

                $data[$k] = [
                    'id' => $v['id'],
                    'name' => $v['name'],
                    'avatar' => $v['avatar'],
                    'lastMsgTime' => '',
                    'content' => '',
                    'workEmployeeId' => $v['id'],
                    'toUserType' => 1,
                    'toUserId' => $workContactId,
                ];

                if (! empty($lastMsg[0])) {
                    $day = date('n-j', (int) ($lastMsg[0]->msg_time * 0.001));
                    $dayArr = explode('-', $day);
                    $msgDataTime = $dayArr[0] . '月' . $dayArr[1] . '日';

                    $data[$k]['lastMsgTime'] = $msgDataTime;
                    $data[$k]['content'] = $this->typeContent((int) $lastMsg[0]->msg_type, $lastMsg[0]->content);
                }
            }
        } else {
            $toData = $this->workContactRoomService->getWorkContactRoomsByContactId($workContactId);
            $roomIds = array_column($toData, 'roomId');
            if (empty($roomIds)) {
                return [];
            }
            $where[] = ['id', 'in', $roomIds];
            $roomList = $this->workRoomClient->getWorkRoomList($where, ['*'], $options);
            foreach ($roomList['data'] as $k => $v) {
                $lastMsg = $this->workMessageService->getWorkMessagesLastByWxRoomId($v['wxChatId'], ['id', 'msg_time', 'content', 'msg_type']);
                $data[$k] = [
                    'id' => $v['id'],
                    'name' => $v['name'],
                    'avatar' => '',
                    'lastMsgTime' => '',
                    'content' => '',
                    'workEmployeeId' => $workContactId,
                    'toUserType' => 2,
                    'toUserId' => $v['id'],
                ];

                if (! empty($lastMsg[0])) {
                    $day = date('n-j', (int) ($lastMsg[0]->msg_time * 0.001));
                    $dayArr = explode('-', $day);
                    $msgDataTime = $dayArr[0] . '月' . $dayArr[1] . '日';
                    $data[$k]['lastMsgTime'] = $msgDataTime;
                    $data[$k]['content'] = $this->typeContent((int) $lastMsg[0]->msg_type, $lastMsg[0]->content);
                }
            }
        }

        return $data;
    }

    /**
     * 获取类型消息.
     * @param int $type ...
     * @param null|string $content ...json
     * @return string ...
     */
    protected function typeContent(int $type, ?string $content): string
    {
        if (empty($content)) {
            return '';
        }
        $contentArr = json_decode($content, true);
        if (empty($contentArr)) {
            return '';
        }
        if ($type === MsgType::TEXT) {
            return $contentArr['content'];
        }
        if (in_array($type, MsgType::$fixedType, true)) {
            return MsgType::getMessage($type);
        }
        return '其它类型消息';
    }

    /**
     * 获取最近一条消息.
     * @param string $wxUserId ...
     * @param string $toIds ...
     * @return array ...
     * @throws \JsonException
     */
    protected function getLastMsg(string $employeeWxId, string $contactWxId): array
    {
        return $this->workMessageService->getLastMessageByEmployeeWxIdAndContactWxId($employeeWxId, $contactWxId);
    }
}
